home *** CD-ROM | disk | FTP | other *** search
- /*
- ** FracBlank - AmigaDOS 2.04 commodities utility screenblanker
- **
- ** Copyright © 1991-1995 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- **
- ** Cosmic flame fractal code derived from xlock source code
- **
- ** Copyright © 1988-1991 by Patrick J. Naughton.
- */
-
- #include <intuition/intuitionbase.h>
- #include <intuition/pointerclass.h>
- #include <intuition/sghooks.h>
-
- #include <workbench/workbench.h>
- #include <workbench/startup.h>
-
- #include <libraries/commodities.h>
- #include <libraries/asl.h>
-
- #include <datatypes/pictureclass.h>
-
- #include <graphics/gfxbase.h>
-
- #include <hardware/custom.h>
-
- #include <exec/interrupts.h>
- #include <exec/execbase.h>
- #include <exec/devices.h>
- #include <exec/memory.h>
-
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <dos/rdargs.h>
-
- #include <clib/commodities_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/datatypes_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/utility_protos.h>
- #include <clib/keymap_protos.h>
- #include <clib/icon_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/asl_protos.h>
-
- #include <pragmas/datatypes_pragmas.h>
- #include <pragmas/utility_pragmas.h>
- #include <pragmas/keymap_pragmas.h>
- #include <pragmas/icon_pragmas.h>
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/asl_pragmas.h>
-
- #include <stdarg.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include <dos.h>
-
- #include "gtlayout.h"
-
- // Use a simple address trick instead of the predefined
- // address in amiga.lib
-
- #ifndef custom
- #define custom (*(struct Custom *)0xDFF000)
- #endif // custom
-
- // Command line arguments
-
- enum { ARG_PRIORITY,
- ARG_POPKEY,
- ARG_POPUP,
- ARG_BLANKSCREEN,
- ARG_SAVESCREEN,
- ARG_FRACTAL,
- ARG_COLOUR,
- ARG_DISPLAYMODE,
- ARG_DEPTH,
- ARG_SCREENTIMEOUT,
- ARG_PATTERNTIMEOUT,
- ARG_MAXRECURSION,
- ARG_MAXDOTS,
-
- ARGCOUNT
- };
-
- // Hotkey IDs
-
- enum { POP_WINDOW,
- BLANK_SCREEN,
- SAVE_SCREEN
- };
-
- // Gadget IDs
-
- enum { GAD_HOTKEY=1000,
- GAD_BLANKSCREEN,
- GAD_SAVESCREEN,
- GAD_MODE,
- GAD_HIDE,
- GAD_SAVE,
- GAD_QUIT
- };
-
- // Error codes
-
- enum { ERR_SystemError = 30000, // CBERR_SYSERR
- ERR_Duplicate, // CBERR_DUP,
- ERR_Version, // CBERR_VERSION,
-
- ERR_BadFilter = 31000, // COERR_BADFILTER,
- ERR_BadType, // COERR_BADTYPE
-
- ERR_NoIntuition = 32000, // intuition.library didn't open
- ERR_NoGfx, // graphics.library didn't open
- ERR_NoAsl, // asl.library didn't open
- ERR_NoCommodities, // commodities.library didn't open
- ERR_NoUtility, // utility.library didn't open
- ERR_NoIcon, // icon.library didn't open
- ERR_ScreenModeRequest, // Couldn't allocate ScreenModeRequester
- ERR_NoColours, // Couldn't allocate colour table
- ERR_NoPointer, // Couldn't create transparent pointer
- ERR_NoControlProcess, // Couldn't create control process
- ERR_NoMsgPort, // Couldn't create msgport
- ERR_NoWindow, // Couldn't open window
- ERR_NoKeymap, // Couldn't open keymap.library
- ERR_NoGTLayout, // Couldn't open gtlayout.library
- };
-
- // All the rawkey codes we know about
-
- #define RAWKEY_CURSOR_UP 76
- #define RAWKEY_CURSOR_DOWN 77
- #define RAWKEY_CURSOR_RIGHT 78
- #define RAWKEY_CURSOR_LEFT 79
-
- #define RAWKEY_F1 80
- #define RAWKEY_F2 81
- #define RAWKEY_F3 82
- #define RAWKEY_F4 83
- #define RAWKEY_F5 84
- #define RAWKEY_F6 85
- #define RAWKEY_F7 86
- #define RAWKEY_F8 87
- #define RAWKEY_F9 88
- #define RAWKEY_F10 89
-
- #define RAWKEY_HELP 95
-
- // Some useful signals
-
- #define SIG_FINISH SIGBREAKF_CTRL_E
- #define SIG_BREAK SIGBREAKF_CTRL_C
- #define SIG_CHANGE SIGBREAKF_CTRL_D
- #define SIG_CYCLE SIGBREAKF_CTRL_E
- #define SIG_START SIGBREAKF_CTRL_F
- #define SIG_REFRESH SIG_START
- #define SIG_WAKEUP SIGBREAKF_CTRL_F
- #define SIG_HANDSHAKE SIGF_SINGLE
- #define SIG_CX (1L << CxPort -> mp_SigBit)
- #define SIG_WINDOW (1L << Window -> UserPort -> mp_SigBit)
-
- // Fractal types
-
- enum { FRACTAL_REAL_PLANE,
- FRACTAL_COSMIC_FLAME,
- FRACTAL_RANDOM
- };
-
- // Colour modes
-
- enum { COLOUR_CYCLE,
- COLOUR_STATIC
- };
-
- // A 96 bit colour entry
-
- typedef struct ColourEntry
- {
- ULONG Red,
- Green,
- Blue;
- } ColourEntry;
-
- // A table of colour entries, ready for LoadRGB32()
-
- typedef struct ColourTable
- {
- WORD NumColours,
- FirstColour;
-
- ColourEntry Entry[1];
-
- ULONG Terminator;
- } ColourTable;
-
- // Spread a byte across a long word
-
- #define SPREAD(v) ((ULONG)(v) << 24 | (ULONG)(v) << 16 | (ULONG)(v) << 8 | (v))
-
- // Program revision tag
-
- UBYTE VersTag[] = "\0$VER: FracBlank 2.3 (9.3.95)";
-
- // Shared library identifiers
-
- extern struct ExecBase *SysBase;
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *CxBase,
- *IconBase,
- *AslBase,
- *UtilityBase,
- *DataTypesBase,
- *KeymapBase,
- *GTLayoutBase;
-
- // The main program
-
- struct Process *MainProcess;
- BOOL PopUp;
-
- // BlankerEntry data
-
- struct SignalSemaphore BlankSemaphore;
- struct Hook ScreenHook,
- WindowHook;
- struct Task *BlankTask;
- ULONG CycleMask;
- LONG CycleBit;
- struct Screen *BlankScreen;
- struct Window *BlankWindow;
- WORD Width,
- Height;
- struct RastPort *RPort;
- struct ViewPort *VPort;
- ULONG Pen;
-
- // A blank pointer
-
- APTR Pointer;
- UWORD Nothing;
- struct BitMap PointerBitMap;
-
- // String editing hook
-
- struct Hook EditHook;
-
- // BlankerControl data
-
- struct Process *BlankerControlProcess;
-
- // Commodities interface data
-
- struct MsgPort *CxPort;
- CxObj *Broker;
- ULONG SpecialQualifier;
-
- // Declarations for cosmic flame blanker code
-
- double Flame[2][3][2];
- WORD FlameLevel,
- FlameAlternateForm;
- WORD FlameWheel,
- FlameColour;
- ULONG FlamePoints;
- ULONG MaxRecursionLevel = 40,
- MaxFlamePoints = 200;
-
- // Key sequence buffers
-
- UBYTE HotkeyBuffer[256],
- BlankScreenBuffer[256],
- SaveScreenBuffer[256];
-
- // Screen and pattern change timeout
-
- ULONG ScreenCount = 0,
- PatternCount = 0,
- ScreenTimeout = 60,
- PatternTimeout = 60;
-
- // Some kind of a semaphore to tell the blank task to stop drawing
-
- BYTE StopDrawing = FALSE;
-
- // sin -45° = cos -45° (saves precious calculation time)
-
- double deg45;
-
- // In case we need to rescale things
-
- double VerticalScale;
-
- // The current colour mode
-
- UBYTE ColourMode = COLOUR_CYCLE;
-
- // The current fractal type
-
- UBYTE FractalType = FRACTAL_RANDOM;
-
- // Colour table data
-
- UBYTE Red[255],
- Green[255],
- Blue[255];
- WORD MaxColour,
- Wheel;
- ColourTable *Colours;
-
- // User interface data
-
- struct Window *Window;
- LayoutHandle *Handle;
-
- // Screen mode requester data
-
- struct ScreenModeRequester *ScreenModeRequest;
- BOOL ResetRequest = FALSE;
- ULONG DisplayID;
- WORD DisplayDepth;
- WORD Depth;
- UBYTE DisplayModeBuffer[DISPLAYNAMELEN + 40];
-
- // The process responsible for saving the screen data to the clipboard
-
- struct Process *Saver;
-
- // A new broker definition, Commodities needs this
-
- struct NewBroker NewBroker =
- {
- NB_VERSION,
- "FracBlank",
- "Fractal screen blanker v2.3",
- "Screen blanker",
- NBU_NOTIFY | NBU_UNIQUE,
- COF_SHOW_HIDE,
- 0,NULL,0
- };
-
- // Prototypes for this module
-
- BOOL GetModeName(ULONG Mode,STRPTR Buffer);
- struct Library * SafeOpenLibrary(STRPTR Name,LONG Version);
- CxObj * CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID);
- void hsv2rgb(double H,double S,double V,UBYTE *r,UBYTE *g,UBYTE *b);
- void hsvramp(double h1,double s1,double b1,double h2,double s2,double b2,int count,UBYTE *red,UBYTE *green,UBYTE *blue);
- VOID StuffChar(VOID);
- VOID __stdargs SPrintf(STRPTR Buffer,STRPTR FormatString,...);
- LONG Atol(STRPTR Buffer);
- STRPTR ToolString(STRPTR *Array,STRPTR Match,STRPTR Default);
- LONG ToolValue(STRPTR *Array,STRPTR Match,LONG Default);
- ULONG BackfillDummy(VOID);
- VOID RotatePalette(VOID);
- VOID BlackScreen(VOID);
- VOID __saveds BlankerControlEntry(VOID);
- ULONG Random(ULONG MaxValue);
- VOID MonoPlot(WORD Left,WORD Top);
- VOID MultiPlot(ULONG Colour,WORD Left,WORD Top);
- VOID RealPlane(VOID);
- BOOL RecurseMono(double x,double y,WORD Level);
- BOOL RecurseColour(double x,double y,WORD Level);
- VOID CosmicFlame(VOID);
- VOID __saveds BlankerEntry(VOID);
- VOID __saveds __stdargs BlankerAction(CxMsg *CxMessage,CxObj *CxObject);
- VOID ShutdownCx(VOID);
- WORD GetSeconds(STRPTR String);
- LONG SetupCx(VOID);
- VOID HandleCxMsg(CxMsg *Message);
- LONG __saveds __stdargs ShowTime(struct Gadget *SomeGadget,WORD Level);
- VOID ShutdownWindow(VOID);
- BOOL SetupWindow(VOID);
- VOID CloseAll(LONG ReturnCode);
- VOID OpenAll(int argc,char **argv);
- VOID UpdateModeString(VOID);
- VOID SaveOptions(char **argv);
- VOID __saveds SaverEntry(VOID);
- ULONG BuildMask(STRPTR Code);
- ULONG AddQualifier(STRPTR Code,ULONG Qualifier);
- ULONG SubQualifier(STRPTR Code,ULONG Qualifier);
- WORD __stdargs ShowRequest(struct Window *Window,STRPTR Text,STRPTR Gadgets,...);
- VOID ReportError(struct Window *Window,STRPTR Template,LONG Error);
- ULONG __saveds __asm EditRoutine(register __a0 struct Hook *Hook,register __a2 struct SGWork *Work,register __a1 ULONG *Msg);
-
- /* EditRoutine():
- *
- * A special string gadget editing routine for key
- * combination input.
- */
-
- ULONG __saveds __asm
- EditRoutine(register __a0 struct Hook *Hook,register __a2 struct SGWork *Work,register __a1 ULONG *Msg)
- {
- struct InputEvent Event;
- ULONG Qualifier;
- UWORD Code;
- UBYTE Key[10];
- WORD KeyLen;
- STRPTR KeyName;
-
- // If the gadget just got activated or the caps lock key
- // is active, don't change anything
-
- if(*Msg == SGH_CLICK || (*Msg == SGH_KEY && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CAPSLOCK)))
- return(TRUE);
- else
- {
- // Complain if this is not what we expect to be fun
-
- if(*Msg != SGH_KEY)
- return(FALSE);
- }
-
- // Ditch the qualifier keys
-
- if(Work -> IEvent -> ie_Code >= 96 && Work -> IEvent -> ie_Code <= 103)
- {
- Work -> Actions &= ~(SGA_USE | SGA_BEEP);
-
- return(TRUE);
- }
-
- // Strip all the qualifiers we don't want
-
- Qualifier = Work -> IEvent -> ie_Qualifier & ~(IEQUALIFIER_REPEAT | IEQUALIFIER_INTERRUPT | IEQUALIFIER_MULTIBROADCAST | IEQUALIFIER_RELATIVEMOUSE);
-
- // Check for raw keys
-
- switch(Work -> IEvent -> ie_Code)
- {
- case RAWKEY_CURSOR_UP:
- case RAWKEY_CURSOR_DOWN:
- case RAWKEY_CURSOR_RIGHT:
- case RAWKEY_CURSOR_LEFT:
-
- // A cursor key was pressed, check if there
- // is probably some special feature involved
-
- if(!(Qualifier & ~(IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
- return(TRUE);
-
- // FALLS THROUGH TO:
-
- case RAWKEY_F1:
- case RAWKEY_F2:
- case RAWKEY_F3:
- case RAWKEY_F4:
- case RAWKEY_F5:
- case RAWKEY_F6:
- case RAWKEY_F7:
- case RAWKEY_F8:
- case RAWKEY_F9:
- case RAWKEY_F10:
-
- case RAWKEY_HELP:
-
- // Ok, so this is a raw key event
-
- Code = Work -> IEvent -> ie_Code;
- KeyLen = 0;
-
- break;
-
- default:
-
- // Make a copy of the inputevent and
- // clear the qualifier bits
-
- CopyMem(Work -> IEvent,&Event,sizeof(struct InputEvent));
-
- Event . ie_Qualifier = NULL;
-
- Code = 0;
-
- // Translate the event
-
- if((KeyLen = MapRawKey(&Event,Key,10,NULL)) < 0)
- KeyLen = 10;
-
- break;
- }
-
- // Is the user holding down a single Amiga key?
-
- if(KeyLen && (Qualifier & IEQUALIFIER_RCOMMAND) && !(Qualifier & ~IEQUALIFIER_RCOMMAND))
- {
- UBYTE Char = ToUpper(Key[0]);
-
- // Undo and clear are supported
-
- if(Char == 'Q' || Char == 'X')
- return(TRUE);
- }
-
- // Can we safely continue?
-
- if((!Code && !KeyLen) || KeyLen > 1 || (!Code && KeyLen && !Key[0]))
- {
- Work -> Actions = (Work -> Actions & ~SGA_USE) | SGA_BEEP;
-
- return(TRUE);
- }
-
- // Take care of special characters
-
- if(KeyLen)
- {
- STATIC struct { UBYTE Code; STRPTR Name; } KeyTable[] =
- {
- '\r', "Return",
- '\b', "Backspace",
- '\033', "Escape",
- ' ', "Spacebar",
- ',', "Comma",
- '\177', "Delete",
- '\t', "Tab",
-
- 0
- };
-
- BOOL GotIt = FALSE;
- WORD i;
-
- // Carriage return was pressed
-
- if(Key[0] == '\r')
- {
- // This probably ends input
-
- if(!Qualifier)
- {
- Work -> Actions = (Work -> Actions & ~SGA_BEEP) | SGA_USE | SGA_END;
-
- return(TRUE);
- }
- else
- {
- // Is this the enter key?
-
- if(Qualifier & IEQUALIFIER_NUMERICPAD)
- {
- KeyName = "Enter";
-
- Qualifier &= ~IEQUALIFIER_NUMERICPAD;
-
- GotIt = TRUE;
- }
- }
- }
-
- // If this is just the tab key, pass it through cleanly
-
- if(Key[0] == '\t' && !(Qualifier & ~(IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
- return(TRUE);
-
- // Now check for special characters
-
- Key[0] = ToUpper(Key[0]);
-
- if(!GotIt)
- {
- for(i = 0 ; KeyTable[i] . Code ; i++)
- {
- if(KeyTable[i] . Code == Key[0])
- {
- KeyName = KeyTable[i] . Name;
-
- GotIt = TRUE;
-
- break;
- }
- }
- }
-
- // If no special character is involved,
- // use the vanilla character code
-
- if(!GotIt)
- {
- if((Key[0] > ' ' && Key[0] < 127) || Key[0] >= 160)
- {
- Key[1] = 0;
-
- KeyName = Key;
- }
- else
- {
- Work -> Actions = (Work -> Actions & ~SGA_USE) | SGA_BEEP;
-
- return(TRUE);
- }
- }
- }
- else
- {
- // Special raw key code table
-
- STATIC struct { UWORD Code; STRPTR Name; } RawTable[] =
- {
- RAWKEY_CURSOR_UP, "Cursor_Up",
- RAWKEY_CURSOR_DOWN, "Cursor_Down",
- RAWKEY_CURSOR_RIGHT, "Cursor_Right",
- RAWKEY_CURSOR_LEFT, "Cursor_Left",
-
- RAWKEY_F1, "F1",
- RAWKEY_F2, "F2",
- RAWKEY_F3, "F3",
- RAWKEY_F4, "F4",
- RAWKEY_F5, "F5",
- RAWKEY_F6, "F6",
- RAWKEY_F7, "F7",
- RAWKEY_F8, "F8",
- RAWKEY_F9, "F9",
- RAWKEY_F10, "F10",
-
- RAWKEY_HELP, "Help",
-
- 0
- };
-
- WORD i;
-
- // One eventually must match
-
- for(i = 0 ; RawTable[i] . Code ; i++)
- {
- if(Code == RawTable[i] . Code)
- {
- KeyName = RawTable[i] . Name;
-
- break;
- }
- }
- }
-
- // Take care of the qualifiers. Note that we do not distinguish
- // between the left and right shift/alt keys
-
- if(Qualifier)
- {
- STATIC struct { ULONG Qualifier; STRPTR Name; } QualifierTable[] =
- {
- IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT, "Shift ",
- IEQUALIFIER_LALT | IEQUALIFIER_RALT, "Alt ",
- IEQUALIFIER_LCOMMAND, "LAmiga ",
- IEQUALIFIER_RCOMMAND, "RAmiga ",
- IEQUALIFIER_LEFTBUTTON, "Left_Button ",
- IEQUALIFIER_MIDBUTTON, "Middle_Button ",
- IEQUALIFIER_RBUTTON, "Right_Button ",
- IEQUALIFIER_NUMERICPAD, "Numeric_Pad ",
-
- 0
- };
-
- WORD i;
-
- // Ok, now start building the string
-
- Work -> WorkBuffer[0] = 0;
-
- for(i = 0 ; QualifierTable[i] . Qualifier ; i++)
- {
- if(Qualifier & QualifierTable[i] . Qualifier)
- strcat(Work -> WorkBuffer,QualifierTable[i] . Name);
- }
-
- // Add the key itself
-
- strcat(Work -> WorkBuffer,KeyName);
-
- // Update the work data
-
- Work -> NumChars = strlen(Work -> WorkBuffer);
- Work -> BufferPos = Work -> NumChars;
-
- // Finished...
-
- Work -> Actions = (Work -> Actions & ~(SGA_BEEP | SGA_PREVACTIVE | SGA_NEXTACTIVE | SGA_END)) | SGA_REDISPLAY | SGA_USE;
- }
- else
- Work -> Actions &= ~(SGA_USE | SGA_BEEP);
-
- return(TRUE);
- }
-
- /* ReportError(struct Window *Window,STRPTR Template,LONG Error):
- *
- * Show an error message.
- */
-
- VOID
- ReportError(struct Window *Window,STRPTR Template,LONG Error)
- {
- STATIC struct { LONG Error; STRPTR Code; } Table[] =
- {
- ERR_SystemError, "Commodities system error; out of memory",
- ERR_Duplicate, "Commodities broker already exists",
- ERR_Version, "Commodities broker version not supported",
-
- ERR_BadFilter, "Bad filter descriptor",
- ERR_BadType, "Bad type descriptor",
-
- ERR_NoIntuition, "Could not open intuition.library v37",
- ERR_NoGfx, "Could not open graphics.library v39",
- ERR_NoAsl, "Could not open asl.library v38",
- ERR_NoCommodities, "Could not open commodities.library v37",
- ERR_NoUtility, "Could not open utility.library v37",
- ERR_NoIcon, "Could not open icon.library v37",
- ERR_ScreenModeRequest, "Could not allocate screen mode requester",
- ERR_NoColours, "Could not allocate colour table; out of memory",
- ERR_NoPointer, "Could not allocate mouse pointer; out of memory",
- ERR_NoControlProcess, "Could not create mouse blanker process",
- ERR_NoMsgPort, "Could not create message port",
- ERR_NoWindow, "Could not open window",
- ERR_NoKeymap, "Could not open keymap.library",
- ERR_NoGTLayout, "Could not open gtlayout.library v9",
-
- 0, NULL
- };
-
- UBYTE LocalBuffer[256];
- STRPTR Buffer;
- BOOL GotIt = FALSE;
- LONG i;
-
- // Look for the corresponding error message.
-
- for(i = 0 ; Table[i] . Error ; i++)
- {
- if(Error == Table[i] . Error)
- {
- Buffer = Table[i] . Code;
-
- GotIt = TRUE;
-
- break;
- }
- }
-
- if(!GotIt)
- {
- if(!Fault(Error,"",LocalBuffer,256))
- return;
-
- Buffer = &LocalBuffer[2];
- }
-
- if(!Template)
- Template = Buffer;
-
- if(MainProcess -> pr_CLI && !Window)
- {
- Printf("FracBlank: ");
- Printf(Template,Buffer);
- Printf("\n");
- }
- else
- ShowRequest(Window,Template,"Continue",Buffer);
- }
-
- /* ShowRequest(struct Window *Window,STRPTR Text,STRPTR Gadgets,...):
- *
- * This routine shows an easy requester. If there is just one
- * button to be pressed, the user will be able to answer it
- * by pressing any key.
- */
-
- WORD __stdargs
- ShowRequest(struct Window *Window,STRPTR Text,STRPTR Gadgets,...)
- {
- if(IntuitionBase)
- {
- struct EasyStruct Easy;
- va_list VarArgs;
- LONG i,GadgetCount;
-
- for(i = GadgetCount = 0 ; i < strlen(Gadgets) ; i++)
- {
- if(Gadgets[i] == '|')
- GadgetCount++;
- }
-
- Easy . es_StructSize = sizeof(struct EasyStruct);
- Easy . es_Flags = NULL;
- Easy . es_Title = "Fractal screen blanker";
- Easy . es_TextFormat = Text;
- Easy . es_GadgetFormat = Gadgets;
-
- if(GadgetCount)
- {
- WORD Result;
-
- if(GTLayoutBase)
- LT_LockWindow(Window);
-
- va_start(VarArgs,Gadgets);
- Result = EasyRequestArgs(Window,&Easy,NULL,VarArgs);
- va_end(VarArgs);
-
- if(GTLayoutBase)
- LT_UnlockWindow(Window);
-
- return(Result);
- }
- else
- {
- struct Window *ReqWindow;
-
- if(GTLayoutBase)
- LT_LockWindow(Window);
-
- va_start(VarArgs,Gadgets);
-
- if(ReqWindow = BuildEasyRequestArgs(Window,&Easy,IDCMP_RAWKEY,VarArgs))
- {
- ULONG IDCMP;
- LONG Result;
-
- FOREVER
- {
- WaitPort(ReqWindow -> UserPort);
-
- IDCMP = NULL;
-
- Result = SysReqHandler(ReqWindow,&IDCMP,FALSE);
-
- if(!Result || (Result == -2 && !(IDCMP & IDCMP_RAWKEY)))
- break;
- }
-
- FreeSysRequest(ReqWindow);
- }
-
- va_end(VarArgs);
-
- if(GTLayoutBase)
- LT_UnlockWindow(Window);
- }
- }
-
- return(0);
- }
-
- /* BuildMask(STRPTR Code):
- *
- * Build a mask of qualifiers covered by the given
- * code.
- */
-
- ULONG
- BuildMask(STRPTR Code)
- {
- IX Expression;
-
- if(!ParseIX(Code,&Expression))
- {
- ULONG Mask = NULL,Bits = Expression . ix_Qualifier & Expression . ix_QualMask;
-
- // Are shift/caps lock keys involved?
-
- if(Bits & IXSYM_CAPSMASK)
- {
- // Are both shift keys equivalent?
-
- if(Expression . ix_QualSame & IXSYM_SHIFT)
- Mask |= IXSYM_SHIFTMASK | (Bits & IEQUALIFIER_CAPSLOCK);
- else
- {
- // Are all shift/caps lock keys equivalent?
-
- if(Expression . ix_QualSame & IXSYM_CAPS)
- Mask |= IXSYM_CAPSMASK;
- else
- Mask |= Bits & IXSYM_CAPSMASK;
- }
- }
-
- // Are alt keys involved?
-
- if(Bits & IXSYM_ALTMASK)
- {
- // Are both alt keys equivalent?
-
- if(Expression . ix_QualSame & IXSYM_ALT)
- Mask |= IXSYM_ALTMASK;
- else
- Mask |= Bits & IXSYM_ALTMASK;
- }
-
- // Take care of the remaining qualifiers
-
- Mask |= Bits & ~(IXSYM_ALTMASK | IXSYM_CAPSMASK);
-
- return(Mask);
- }
- else
- return(NULL);
- }
-
- /* AddQualifier(STRPTR Code,ULONG Qualifier):
- *
- * Add to the qualifier mask.
- */
-
- ULONG
- AddQualifier(STRPTR Code,ULONG Qualifier)
- {
- return(Qualifier | BuildMask(Code));
- }
-
- /* SubQualifier(STRPTR Code,ULONG Qualifier):
- *
- * Remove keys from the qualifier mask.
- */
-
- ULONG
- SubQualifier(STRPTR Code,ULONG Qualifier)
- {
- return(Qualifier & ~BuildMask(Code));
- }
-
- /* GetModeName(ULONG Mode,STRPTR Buffer):
- *
- * This routine supplies the name for a DisplayID.
- */
-
- BOOL
- GetModeName(ULONG Mode,STRPTR Buffer)
- {
- struct NameInfo NameInfo;
-
- if(GetDisplayInfoData(NULL,(APTR)&NameInfo,sizeof(struct NameInfo),DTAG_NAME,Mode))
- strcpy(Buffer,NameInfo . Name);
- else
- {
- struct DisplayInfo DisplayInfo;
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,Mode))
- {
- struct DimensionInfo DimensionInfo;
-
- if(GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(struct DimensionInfo),DTAG_DIMS,Mode))
- {
- STRPTR MonitorName;
-
- switch(Mode & MONITOR_ID_MASK)
- {
- case NTSC_MONITOR_ID:
-
- MonitorName = "NTSC:";
- break;
-
- case PAL_MONITOR_ID:
-
- MonitorName = "PAL:";
- break;
-
- case VGA_MONITOR_ID:
-
- MonitorName = "VGA:";
- break;
-
- case A2024_MONITOR_ID:
-
- MonitorName = "A2024:";
- break;
-
- default:
-
- MonitorName = "";
- break;
- }
-
- if(DisplayInfo . PropertyFlags & DIPF_IS_HAM)
- SPrintf(Buffer,"%s%ld × %ld HAM",MonitorName,DimensionInfo . TxtOScan . MaxX - DimensionInfo . TxtOScan . MinX + 1,DimensionInfo . TxtOScan . MaxY - DimensionInfo . TxtOScan . MinY + 1);
- else
- SPrintf(Buffer,"%s%ld × %ld",MonitorName,DimensionInfo . TxtOScan . MaxX - DimensionInfo . TxtOScan . MinX + 1,DimensionInfo . TxtOScan . MaxY - DimensionInfo . TxtOScan . MinY + 1);
- }
- else
- return(FALSE);
- }
- else
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- /* SafeOpenLibrary(STRPTR Name,LONG Version):
- *
- * Just like OpenLibrary, but makes sure that old
- * library versions get flushed from memory.
- */
-
- struct Library *
- SafeOpenLibrary(STRPTR Name,LONG Version)
- {
- struct Library *Base;
-
- Forbid();
-
- if(Base = (struct Library *)FindName(&SysBase -> LibList,FilePart(Name)))
- {
- if(Base -> lib_Version < Version)
- RemLibrary(Base);
- }
-
- Permit();
-
- return(OpenLibrary(Name,Version));
- }
-
- /* CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID):
- *
- * A replacement for the HotKey() routine found in
- * amiga.lib.
- */
-
- CxObj *
- CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
- {
- CxObj *Filter;
-
- if(Filter = CxFilter(Code))
- {
- CxObj *Sender;
-
- if(Sender = CxSender(Port,ID))
- {
- CxObj *Translator;
-
- AttachCxObj(Filter,Sender);
-
- if(Translator = CxTranslate(NULL))
- {
- AttachCxObj(Filter,Translator);
-
- if(!CxObjError(Filter))
- return(Filter);
- }
- }
-
- DeleteCxObjAll(Filter);
- }
-
- return(NULL);
- }
-
- /* hsv2rgb(double H,double S,double V,UBYTE *r,UBYTE *g,UBYTE *b):
- *
- * Convert HSV (hue, saturation, value) colour index into
- * plain RGB (red, green, blue) colour space.
- */
-
- void
- hsv2rgb(double H,double S,double V,UBYTE *r,UBYTE *g,UBYTE *b)
- {
- int i;
- double f,bb;
- UBYTE p,q,t;
-
- H -= floor(H);
- H *= 6.0;
- i = floor(H);
- f = H - (double)i;
- bb = 255.0 * V;
- p = (UBYTE)(bb * (1.0 - S));
- q = (UBYTE)(bb * (1.0 - (S * f)));
- t = (UBYTE)(bb * (1.0 - (S * (1.0 - f))));
-
- switch(i)
- {
- case 0: *r = (UBYTE)bb;
- *g = t;
- *b = p;
- break;
-
- case 1: *r = q;
- *g = (UBYTE)bb;
- *b = p;
- break;
-
- case 2: *r = p;
- *g = (UBYTE)bb;
- *b = t;
- break;
-
- case 3: *r = p;
- *g = q;
- *b = (UBYTE)bb;
- break;
-
- case 4: *r = t;
- *g = p;
- *b = (UBYTE)bb;
- break;
-
- case 5: *r = (UBYTE)bb;
- *g = p;
- *b = q;
- break;
- }
- }
-
- /* hsvramp():
- *
- * Creates a ramp within HSV colour space, showing all
- * colours of the HSV circle.
- */
-
- void
- hsvramp(double h1,double s1,double b1,double h2,double s2,double b2,int count,UBYTE *red,UBYTE *green,UBYTE *blue)
- {
- double dh,ds,db;
-
- dh = (h2 - h1) / count;
- ds = (s2 - s1) / count;
- db = (b2 - b1) / count;
-
- while(count--)
- {
- hsv2rgb(h1,s1,b1,red++,green++,blue++);
-
- h1 += dh;
- s1 += ds;
- b1 += db;
- }
- }
-
- VOID
- StuffChar()
- {
- __emit(0x16C0); // MOVE D0,(A3)+
- }
-
- /* SPrintf(STRPTR Buffer,STRPTR FormatString,...):
- *
- * String formatting routine, similar to sprintf().
- */
-
- VOID __stdargs
- SPrintf(STRPTR Buffer,STRPTR FormatString,...)
- {
- va_list VarArgs;
-
- va_start(VarArgs,FormatString);
- RawDoFmt(FormatString,VarArgs,(VOID (*)())StuffChar,Buffer);
- va_end(VarArgs);
- }
-
- /* Atol(STRPTR Buffer):
- *
- * Convert a string into a long word.
- */
-
- LONG
- Atol(STRPTR Buffer)
- {
- LONG Result;
-
- StrToLong(Buffer,&Result);
-
- return(Result);
- }
-
- /* ToolString(STRPTR *Array,STRPTR Match,STRPTR Default):
- *
- * Return the matching tooltype value, if available.
- * Otherwise do with the default value.
- */
-
- STRPTR
- ToolString(STRPTR *Array,STRPTR Match,STRPTR Default)
- {
- if(Array)
- {
- STRPTR String;
-
- if(String = FindToolType(Array,Match))
- return(String);
- }
-
- return(Default);
- }
-
- /* ToolValue(STRPTR *Array,STRPTR Match,LONG Default):
- *
- * Return the matching tooltype value, if available.
- * Otherwise do with the default value.
- */
-
- LONG
- ToolValue(STRPTR *Array,STRPTR Match,LONG Default)
- {
- if(Array)
- {
- STRPTR String;
-
- if(String = FindToolType(Array,Match))
- {
- LONG Result;
-
- if(StrToLong(String,&Result) > 0)
- return(Result);
- }
- }
-
- return(Default);
- }
-
- /* BackfillDummy():
- *
- * A no-op backfill routine, we'll clear the screen manually.
- */
-
- ULONG
- BackfillDummy()
- {
- return(TRUE);
- }
-
- /* RotatePalette():
- *
- * Fill in the screen palette with new data.
- */
-
- VOID
- RotatePalette()
- {
- WORD i,Index = Wheel;
-
- for(i = 1 ; i <= MaxColour ; i++)
- {
- Colours -> Entry[i] . Red = SPREAD(Red[Index]);
- Colours -> Entry[i] . Green = SPREAD(Green[Index]);
- Colours -> Entry[i] . Blue = SPREAD(Blue[Index]);
-
- Index = (Index + 1) % MaxColour;
- }
-
- // Terminate the table, just in case...
-
- Colours -> Entry[Colours -> NumColours] . Red = 0;
- }
-
- /* BlackScreen():
- *
- * Clear the screen, this is accomplished by first setting the
- * screen colours to black, clearing the screen and finally
- * restoring the palette.
- */
-
- VOID
- BlackScreen()
- {
- WORD Count;
-
- Count = Colours -> NumColours;
-
- Colours -> NumColours = MaxColour + 1;
-
- memset(&Colours -> Entry[0],0,256 * sizeof(ColourEntry));
-
- LoadRGB32(VPort,(ULONG *)Colours);
-
- SetRast(RPort,0);
-
- Colours -> NumColours = Count;
-
- RotatePalette();
-
- LoadRGB32(VPort,(ULONG *)Colours);
- }
-
- /* BlankerControlEntry():
- *
- * The screen blanker control task.
- */
-
- VOID __saveds
- BlankerControlEntry()
- {
- ULONG SignalSet;
-
- Forbid();
-
- // Ring back...
-
- Signal(MainProcess,SIG_HANDSHAKE);
-
- FOREVER
- {
- // Wait for something to happen
-
- SignalSet = Wait(SIG_BREAK | SIG_START | SIG_CHANGE | SIG_FINISH);
-
- // Remove both the screen and the blanker task?
-
- if(SignalSet & (SIG_BREAK | SIG_FINISH))
- {
- ObtainSemaphore(&BlankSemaphore);
-
- if(BlankScreen)
- ScreenToBack(BlankScreen);
-
- // Remove the blanker task
-
- if(BlankTask)
- {
- SetSignal(0,SIG_HANDSHAKE);
-
- // Tell the blanker task to shut down
-
- Signal(BlankTask,SIG_BREAK);
-
- // Move the blanker task priority up,
- // we don't want the low priority task
- // to wait until some high priority task
- // yields CPU time
-
- SetTaskPri(BlankTask,127);
-
- // Wait for handshake signal...
-
- Wait(SIG_HANDSHAKE);
-
- // He's dead, Jim
-
- BlankTask = NULL;
- }
-
- // Close the blanker screen
-
- if(BlankScreen)
- {
- ScreenToBack(BlankScreen);
-
- CloseWindow(BlankWindow);
-
- BlankWindow = NULL;
-
- CloseScreen(BlankScreen);
-
- BlankScreen = NULL;
- }
-
- ReleaseSemaphore(&BlankSemaphore);
-
- SignalSet &= ~(SIG_CHANGE | SIG_START);
- }
-
- // Leave the town?
-
- if(SignalSet & SIG_FINISH)
- break;
-
- // Start the screen blanker?
-
- if(SignalSet & SIG_START)
- {
- // Is the screen already open?
-
- if(!BlankScreen)
- {
- ULONG LocalID;
-
- // Use the default public screen display ID
- // if necessary
-
- if(DisplayID == INVALID_ID || (ModeNotAvailable(DisplayID) & ~DI_AVAIL_NOTWITHGENLOCK))
- {
- struct Screen *PubScreen = LockPubScreen(NULL);
-
- if(PubScreen)
- {
- LocalID = GetVPModeID(&PubScreen -> ViewPort);
-
- UnlockPubScreen(NULL,PubScreen);
- }
- else
- LocalID = INVALID_ID;
- }
- else
- LocalID = DisplayID;
-
- // Did we get a valid ID?
-
- if(LocalID != INVALID_ID)
- {
- WORD LocalDepth;
- struct DimensionInfo DimensionInfo;
- struct DisplayInfo DisplayInfo;
-
- // Choose the right display depth
-
- LocalDepth = Depth;
-
- if(GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(DimensionInfo),DTAG_DIMS,LocalID))
- {
- if(!LocalDepth)
- {
- if((LocalDepth = DimensionInfo . MaxDepth) > 8)
- LocalDepth = 8;
- }
- else
- {
- if(LocalDepth > DimensionInfo . MaxDepth)
- LocalDepth = DimensionInfo . MaxDepth;
- }
- }
- else
- {
- if(!LocalDepth)
- LocalDepth = 2;
- }
-
- // Compensate for the display aspect ratio
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(DisplayInfo),DTAG_DISP,LocalID))
- {
- if(DisplayInfo . Resolution . y)
- {
- double x,y;
-
- x = (double)DisplayInfo . Resolution . x;
- y = (double)DisplayInfo . Resolution . y;
-
- VerticalScale = x / y;
- }
- else
- VerticalScale = 1.0;
- }
- else
- VerticalScale = 1.0;
-
- // Set the colour table to black
-
- MaxColour = (1 << LocalDepth) - 1;
-
- Colours -> NumColours = MaxColour + 1;
-
- memset(&Colours -> Entry[0],0,256 * sizeof(ColourEntry));
-
- // Now open the screen and the window
-
- ObtainSemaphore(&BlankSemaphore);
-
- if(BlankScreen = OpenScreenTags(NULL,
- SA_Behind, TRUE,
- SA_Quiet, TRUE,
- SA_DisplayID, LocalID,
- SA_Overscan, OSCAN_MAX,
- SA_Depth, LocalDepth,
- SA_ShowTitle, FALSE,
- SA_BackFill, &ScreenHook,
- SA_Colors32, Colours,
- SA_Draggable, FALSE,
- SA_Exclusive, TRUE,
- TAG_DONE))
- {
- VPort = &BlankScreen -> ViewPort;
- Width = BlankScreen -> Width;
- Height = BlankScreen -> Height;
-
- // To keep the ball rolling...
-
- if((DisplayDepth = LocalDepth) == 1)
- {
- MaxColour = 255;
-
- Colours -> NumColours = 2;
- }
-
- // Create a nice colour table
-
- hsvramp(0.0,1.0,1.0,1.0,1.0,1.0,MaxColour,Red,Green,Blue);
-
- Wheel = Random(MaxColour);
-
- RotatePalette();
-
- // Open the window
-
- if(BlankWindow = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, 0,
- WA_Width, Width,
- WA_Height, Height,
- WA_Backdrop, TRUE,
- WA_Borderless, TRUE,
- WA_Pointer, Pointer,
- WA_CustomScreen, BlankScreen,
- WA_Activate, TRUE,
- WA_RMBTrap, TRUE,
- WA_BackFill, &WindowHook,
- TAG_DONE))
- {
- RPort = BlankWindow -> RPort;
-
- SetABPenDrMd(RPort,Pen = 1,0,JAM1);
-
- // Clear the screen
-
- SetRast(RPort,0);
-
- LoadRGB32(VPort,(ULONG *)Colours);
-
- // Display the screen
-
- ScreenToFront(BlankScreen);
-
- PatternCount = 0;
-
- // Wait for something to happen
-
- Forbid();
-
- BlankTask = (struct Task *)CreateTask("« FracBlank BlankerEntry Task »",127,BlankerEntry,4096 + 400 * MaxRecursionLevel);
-
- SetSignal(0,SIG_HANDSHAKE);
-
- Wait(SIG_HANDSHAKE);
-
- Permit();
- }
- else
- {
- CloseScreen(BlankScreen);
-
- BlankScreen = NULL;
- }
- }
- }
-
- ReleaseSemaphore(&BlankSemaphore);
- }
- else
- {
- // Push the blanker screen to the front if necessary
-
- if(BlankScreen -> TopEdge > 0)
- MoveScreen(BlankScreen,0,-BlankScreen -> TopEdge);
-
- if(IntuitionBase -> FirstScreen != BlankScreen)
- ScreenToFront(BlankScreen);
-
- if(IntuitionBase -> ActiveWindow != BlankWindow)
- ActivateWindow(BlankWindow);
- }
-
- SignalSet &= ~SIG_CHANGE;
- }
-
- // Change the patterns?
-
- if(SignalSet & SIG_CHANGE)
- {
- if(BlankTask)
- {
- // Stop drawing patterns
-
- StopDrawing = TRUE;
-
- Signal(BlankTask,SIG_CHANGE);
- }
- }
- }
-
- BlankerControlProcess = NULL;
-
- Signal(MainProcess,SIG_HANDSHAKE);
- }
-
- /* Random(ULONG MaxValue):
- *
- * Simple random number generation routine.
- */
-
- ULONG
- Random(ULONG MaxValue)
- {
- if(MaxValue)
- {
- STATIC ULONG RandomSeed = 3735879991;
-
- RandomSeed = RandomSeed * custom . vhposr + 3780343439;
-
- return(RandomSeed % MaxValue);
- }
- else
- return(0);
- }
-
- /* MonoPlot(WORD Left,WORD Top):
- *
- * Set a pixel somewhere on the screen.
- */
-
- VOID
- MonoPlot(WORD Left,WORD Top)
- {
- if(Left >= 0 && Left < Width && Top >= 0 && Top < Height)
- WritePixel(RPort,Left,Top);
- }
-
- /* MultiPlot(ULONG Colour,WORD Left,WORD Top):
- *
- * Set a coloured pixel somewhere on the screen.
- */
-
- VOID
- MultiPlot(ULONG Colour,WORD Left,WORD Top)
- {
- if(Left >= 0 && Left < Width && Top >= 0 && Top < Height)
- {
- if(Pen != Colour)
- SetAPen(RPort,Pen = Colour);
-
- WritePixel(RPort,Left,Top);
- }
- }
-
- /* RealPlane():
- *
- * Draw real plane fractals.
- */
-
- VOID
- RealPlane()
- {
- UWORD OffsetX = Width / 2,OffsetY = Height / 2;
- ULONG Signals;
- double x = 0,y = 0,yy,a,b,c,sx,sy,mag;
-
- // Are we running in monochrome mode?
-
- if(DisplayDepth == 1)
- {
- // Provide starting numbers for the fractal
- // parameters
-
- a = (double)(Random(700) + 5) / 100;
- b = (double)(Random(190) + 5) / 100;
- c = (double)(Random( 90) + 5) / 100;
-
- mag = (double)(1 << (Random(6) + 2)) * deg45;
-
- // Go into fractal generation loop
-
- FOREVER
- {
- Signals = SetSignal(0,SIG_BREAK | SIG_CHANGE | CycleMask);
-
- // Are we to shut down?
-
- if(Signals & SIG_BREAK)
- {
- Forbid();
-
- Signal(BlankerControlProcess,SIG_HANDSHAKE);
-
- FreeSignal(CycleBit);
-
- RemTask(NULL);
- }
-
- /* The original formula looks like
- * this:
- * ½
- * x = y - SIGN(x) × ABS(b × x - c)
- * y = a - x
- *
- * I have split the calculation into
- * several steps to save time and
- * variables.
- */
-
- yy = a - x;
-
- if(x < 0)
- x = y + sqrt(fabs(b * x - c));
- else
- x = y - sqrt(fabs(b * x - c));
-
- y = yy;
-
- /* The resulting image appears to have
- * been rotated by 45°, so we'll
- * rotate the pixel coordinates by -45°
- *
- * x = x × cos(alpha) + y × sin(alpha)
- * y = -x × sin(alpha) + y × cos(alpha)
- *
- * We also magnify the image (i.e. the
- * distribution of pixels) in the following
- * lines.
- */
-
- sx = mag * ( x + y);
- sy = mag * VerticalScale * (-x + y);
-
- // If the pixel happens to reside within
- // the boundaries of the screen, draw it.
-
- MonoPlot((WORD)(sx) + OffsetX,(WORD)(sy) + OffsetY);
-
- // Change the pattern?
-
- if(Signals & SIG_CHANGE)
- {
- BlackScreen();
-
- StopDrawing = FALSE;
-
- x = y = 0;
-
- a = (double)(Random(700) + 5) / 100;
- b = (double)(Random(190) + 5) / 100;
- c = (double)(Random( 90) + 5) / 100;
-
- mag = (double)(1 << (Random(6) + 2)) * deg45;
-
- Signals &= ~CycleMask;
- }
-
- // Cycle the colours?
-
- if(Signals & CycleMask)
- {
- LoadRGB32(VPort,(ULONG *)Colours);
-
- Wheel = (Wheel + 1) % MaxColour;
-
- RotatePalette();
- }
- }
- }
- else
- {
- UWORD Count = 0;
- WORD Colour;
-
- a = (double)(Random(700) + 5) / 100;
- b = (double)(Random(190) + 5) / 100;
- c = (double)(Random( 90) + 5) / 100;
-
- mag = (double)(1 << (Random(6) + 2)) * deg45;
-
- Colour = Random(MaxColour - 1) + 1;
-
- FOREVER
- {
- Signals = SetSignal(0,SIG_BREAK | SIG_CHANGE | CycleMask);
-
- if(Signals & SIG_BREAK)
- {
- Forbid();
-
- Signal(BlankerControlProcess,SIG_HANDSHAKE);
-
- FreeSignal(CycleBit);
-
- RemTask(NULL);
- }
-
- yy = a - x;
-
- if(x < 0)
- x = y + sqrt(fabs(b * x - c));
- else
- x = y - sqrt(fabs(b * x - c));
-
- y = yy;
-
- sx = mag * ( x + y);
- sy = mag * VerticalScale * (-x + y);
-
- MultiPlot(Colour,(WORD)(sx) + OffsetX,(WORD)(sy) + OffsetY);
-
- /* Oh well, it's not that easy to
- * produce decent colour values for
- * the pixels to be rendered.
- *
- * The following statement will change
- * the current drawing pen after exactly
- * 1200 pixels have been rendered and will
- * pick a new colour between 1 and 31.
- */
-
- if(Count++ >= 1200)
- {
- WORD NewColour;
-
- Count = 0;
-
- do
- NewColour = Random(MaxColour - 1) + 1;
- while(NewColour == Colour);
-
- Colour = NewColour;
- }
-
- if(Signals & SIG_CHANGE)
- {
- BlackScreen();
-
- StopDrawing = FALSE;
-
- x = y = 0;
-
- a = (double)(Random(700) + 5) / 100;
- b = (double)(Random(190) + 5) / 100;
- c = (double)(Random( 90) + 5) / 100;
-
- mag = (double)(1 << (Random(6) + 2)) * deg45;
-
- Signals &= ~CycleMask;
- }
-
- if(Signals & CycleMask)
- {
- LoadRGB32(VPort,(ULONG *)Colours);
-
- Wheel = (Wheel + 1) % MaxColour;
-
- RotatePalette();
- }
- }
- }
- }
-
- /* RecurseMono(double x,double y,WORD Level):
- *
- * Cosmic flame calculation routine (monochrome).
- */
-
- BOOL
- RecurseMono(double x,double y,WORD Level)
- {
- ULONG Signals = SetSignal(0,SIG_BREAK | SIG_CHANGE | CycleMask);
-
- // Are we to shut down?
-
- if(Signals & SIG_BREAK)
- {
- Forbid();
-
- Signal(BlankerControlProcess,SIG_HANDSHAKE);
-
- FreeSignal(CycleBit);
-
- RemTask(NULL);
- }
-
- // Return to top level?
-
- if(StopDrawing)
- {
- FlameLevel = 0;
- StopDrawing = FALSE;
-
- return(FALSE);
- }
-
- // Change the pattern?
-
- if(Signals & SIG_CHANGE)
- {
- FlameLevel = 0;
- StopDrawing = FALSE;
-
- return(FALSE);
- }
-
- // Cycle the colours?
-
- if(Signals & CycleMask)
- {
- LoadRGB32(VPort,(ULONG *)Colours);
-
- Wheel = (Wheel + 1) % MaxColour;
-
- RotatePalette();
- }
-
- if(Level >= MaxRecursionLevel)
- {
- if((FlamePoints++) > MaxFlamePoints * 100)
- return(FALSE);
- else
- MonoPlot((WORD)((Width / 2) * (x + 1.0)),(WORD)((Height / 2) * VerticalScale * (y + 1.0)));
- }
- else
- {
- double nx,ny;
- WORD i;
-
- for(i = 0 ; i < 2 ; i++)
- {
- nx = Flame[0][0][i] * x + Flame[0][1][i] * y + Flame[0][2][i];
- ny = Flame[1][0][i] * x + Flame[1][1][i] * y + Flame[1][2][i];
-
- if(i < FlameAlternateForm)
- {
- nx = sin(nx);
- ny = sin(ny);
- }
-
- if(!StopDrawing)
- {
- if(!RecurseMono(nx,ny,Level + 1))
- return(FALSE);
- }
- else
- return(FALSE);
- }
- }
-
- return(TRUE);
- }
-
- /* RecurseColour(double x,double y,WORD Level):
- *
- * Cosmic flame calculation routine (colour).
- */
-
- BOOL
- RecurseColour(double x,double y,WORD Level)
- {
- ULONG Signals = SetSignal(0,SIG_BREAK | SIG_CHANGE | CycleMask);
-
- if(Signals & SIG_BREAK)
- {
- Forbid();
-
- Signal(BlankerControlProcess,SIG_HANDSHAKE);
-
- FreeSignal(CycleBit);
-
- RemTask(NULL);
- }
-
- if(StopDrawing)
- {
- FlameLevel = 0;
- StopDrawing = FALSE;
-
- return(FALSE);
- }
-
- /* Change the pattern? */
-
- if(Signals & SIG_CHANGE)
- {
- FlameLevel = 0;
- StopDrawing = FALSE;
-
- return(FALSE);
- }
-
- // Cycle the colours?
-
- if(Signals & CycleMask)
- {
- LoadRGB32(VPort,(ULONG *)Colours);
-
- Wheel = (Wheel + 1) % MaxColour;
-
- RotatePalette();
- }
-
- if(Level >= MaxRecursionLevel)
- {
- if((FlamePoints++) > MaxFlamePoints * 100)
- return(FALSE);
- else
- MultiPlot(FlameColour,(WORD)((Width / 2) * (x + 1.0)),(WORD)((Height / 2) * VerticalScale * (y + 1.0)));
- }
- else
- {
- double nx,ny;
- WORD i;
-
- for(i = 0 ; i < 2 ; i++)
- {
- nx = Flame[0][0][i] * x + Flame[0][1][i] * y + Flame[0][2][i];
- ny = Flame[1][0][i] * x + Flame[1][1][i] * y + Flame[1][2][i];
-
- if(i < FlameAlternateForm)
- {
- nx = sin(nx);
- ny = sin(ny);
- }
-
- if(!StopDrawing)
- {
- if(!RecurseColour(nx,ny,Level + 1))
- return(FALSE);
- }
- else
- return(FALSE);
- }
- }
-
- return(TRUE);
- }
-
- /* CosmicFlame():
- *
- * The cosmic flame screen blanker.
- *
- * xlock.c - X11 client to lock a display and show a screen saver.
- *
- * Copyright (c) 1988-91 by Patrick J. Naughton.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- */
-
- VOID
- CosmicFlame()
- {
- WORD i,j,k;
- BOOL Alternate = FALSE;
-
- FlameLevel = 0;
-
- // Monochrome mode?
-
- if(DisplayDepth == 1)
- {
- // Go into fractal generation loop
-
- FOREVER
- {
- if(!((FlameLevel++) % MaxRecursionLevel))
- {
- BlackScreen();
-
- Alternate = !Alternate;
- }
-
- if(Alternate)
- FlameAlternateForm = 0;
- else
- FlameAlternateForm = Random(2) + 2;
-
- for(k = 0 ; k < 2 ; k++)
- {
- for(i = 0 ; i < 2 ; i++)
- {
- for(j = 0; j < 3; j++)
- Flame[i][j][k] = ((double)Random(1024)) / 512.0 - 1.0;
- }
- }
-
- FlamePoints = 0;
-
- RecurseMono(0.0,0.0,0);
- }
- }
- else
- {
- FlameColour = Random(MaxColour - 1) + 1;
-
- FOREVER
- {
- if(!((FlameLevel++) % MaxRecursionLevel))
- {
- BlackScreen();
-
- Alternate = !Alternate;
- }
- else
- {
- WORD NewColour;
-
- do
- NewColour = Random(MaxColour - 1) + 1;
- while(NewColour == FlameColour);
-
- FlameColour = NewColour;
- }
-
- if(Alternate)
- FlameAlternateForm = 0;
- else
- FlameAlternateForm = Random(2) + 2;
-
- for(k = 0 ; k < 2 ; k++)
- {
- for(i = 0 ; i < 2 ; i++)
- {
- for(j = 0; j < 3; j++)
- Flame[i][j][k] = ((double)Random(1024)) / 512.0 - 1.0;
- }
- }
-
- FlamePoints = 0;
-
- RecurseColour(0.0,0.0,0);
- }
- }
- }
-
- /* BlankerEntry():
- *
- * The screen blanker itself.
- */
-
- VOID __saveds
- BlankerEntry()
- {
- LONG CycleBit;
-
- Forbid();
-
- // Shouldn't go wrong right now, this is the second
- // action this task takes, about 16 signal bits
- // should still be vacant
-
- if((CycleBit = AllocSignal(-1)) != -1)
- {
- CycleMask = (1L << CycleBit);
-
- // Tell the control process we're running
-
- Signal(BlankerControlProcess,SIG_HANDSHAKE);
-
- // Now step back
-
- SetTaskPri(SysBase -> ThisTask,-20);
-
- Permit();
-
- // Determine the fractal type
-
- if(FractalType == FRACTAL_COSMIC_FLAME)
- CosmicFlame();
- else
- {
- if(FractalType == FRACTAL_REAL_PLANE)
- RealPlane();
- else
- {
- if(Random(42) >= 21)
- CosmicFlame();
- else
- RealPlane();
- }
- }
- }
- else
- {
- // Wave goodbye
-
- BlankTask = NULL;
-
- Signal(BlankerControlProcess,SIG_HANDSHAKE);
- }
- }
-
- /* BlankerAction(CxMsg *CxMessage,CxObj *CxObject):
- *
- * Commodities support routine, handles the Commodities
- * custom actions (in this case: filter the InputEvents
- * coming in and enable/disable the screen blanker).
- */
-
- VOID __saveds __stdargs
- BlankerAction(CxMsg *CxMessage,CxObj *CxObject)
- {
- STATIC BYTE Count = 0;
-
- struct InputEvent *Event = (struct InputEvent *)CxMsgData(CxMessage);
-
- // Push the blanker screen to the front if necessary
-
- ObtainSemaphoreShared(&BlankSemaphore);
-
- if(BlankScreen)
- Signal(BlankerControlProcess,SIG_REFRESH);
-
- ReleaseSemaphore(&BlankSemaphore);
-
- // This looks like a timer event
-
- if(Event -> ie_Class == IECLASS_TIMER)
- {
- if(!Window)
- {
- // Screen blanker still inactive?
-
- ObtainSemaphoreShared(&BlankSemaphore);
-
- if(!BlankTask)
- {
- // Is there a timeout to take care of?
-
- if(ScreenTimeout && !Window)
- {
- // Are we ready to create the
- // screenblanker?
-
- if(ScreenCount++ >= ScreenTimeout * 10)
- Signal(BlankerControlProcess,SIG_START);
- }
- }
- else
- {
- // Every 5/10 second we signal the blanker
- // task to rotate the palette.
-
- if(ColourMode == COLOUR_CYCLE)
- {
- if(Count++ >= 2)
- {
- Signal(BlankTask,CycleMask);
-
- Count = 0;
- }
- }
-
- // Is it time to change the pattern?
-
- if(PatternTimeout)
- {
- if(PatternCount++ >= PatternTimeout * 10)
- {
- Signal(BlankerControlProcess,SIG_CHANGE);
-
- PatternCount = 0;
- }
- }
- }
-
- ReleaseSemaphore(&BlankSemaphore);
- }
- }
- else
- {
- // The following lines determine whether
- // the blanker is to be removed or to
- // be left running.
-
- switch(Event -> ie_Class)
- {
- case IECLASS_RAWKEY:
-
- if(!(Event -> ie_Code & IECODE_UP_PREFIX) && !(Event -> ie_Qualifier & SpecialQualifier))
- Signal(BlankerControlProcess,SIG_BREAK);
-
- break;
-
- case IECLASS_NEWPOINTERPOS:
- case IECLASS_POINTERPOS:
- case IECLASS_RAWMOUSE:
-
- Signal(BlankerControlProcess,SIG_BREAK);
-
- break;
- }
-
- ScreenCount = 0;
- }
- }
-
- /* ShutdownCx():
- *
- * Close the Commodities interface.
- */
-
- VOID
- ShutdownCx()
- {
- if(CxPort)
- {
- struct Message *Message;
-
- // Remove the broker
-
- if(Broker)
- DeleteCxObjAll(Broker);
-
- // Remove the MsgPort from the public list
-
- RemPort(CxPort);
-
- // Remove all pending messages
-
- while(Message = GetMsg(CxPort))
- ReplyMsg(Message);
-
- // Delete the MsgPort
-
- DeleteMsgPort(CxPort);
-
- CxPort = NULL;
- Broker = NULL;
- }
- }
-
- /* GetSeconds(STRPTR String):
- *
- * Calculates the number of seconds corresponding to
- * expressions such as `11:25' or `10'.
- */
-
- WORD
- GetSeconds(STRPTR String)
- {
- UBYTE Buffer[10];
- WORD i,Seconds;
-
- CopyMem(String,Buffer,9);
-
- Buffer[9] = 0;
-
- String = Buffer;
-
- for(i = strlen(String) - 1 ; i >= 0 ; i--)
- {
- if(String[i] == ':')
- {
- Seconds = Atol(&String[i + 1]);
-
- String[i] = 0;
-
- Seconds += 60 * Atol(String);
-
- if(Seconds > 30 * 60)
- Seconds = 30 * 60;
-
- return(Seconds);
- }
- }
-
- if((Seconds = Atol(String)) > 30 * 60)
- Seconds = 30 * 60;
-
- return(Seconds);
- }
-
- /* SetupCx():
- *
- * Set up the Commodities interface.
- */
-
- LONG
- SetupCx()
- {
- LONG Error;
-
- // Cancel any previously made assignments
-
- ShutdownCx();
-
- // Create a reply port
-
- if(CxPort = CreateMsgPort())
- {
- // Fill in a unique name
-
- CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
-
- // Add the reply port to the public list
-
- AddPort(CxPort);
-
- // Install the replyport
-
- NewBroker . nb_Port = CxPort;
-
- // Create the broker
-
- if(Broker = CxBroker(&NewBroker,&Error))
- {
- CxObj *ObjectList;
-
- // Link the hotkeys
-
- AttachCxObj(Broker,CustomHotKey(HotkeyBuffer, CxPort,POP_WINDOW));
- AttachCxObj(Broker,CustomHotKey(BlankScreenBuffer, CxPort,BLANK_SCREEN));
- AttachCxObj(Broker,CustomHotKey(SaveScreenBuffer, CxPort,SAVE_SCREEN));
-
- // Install the plain InputEvent handler
-
- ObjectList = CxCustom(BlankerAction,NULL);
-
- // Any accumulated errors?
-
- if(!(Error = CxObjError(ObjectList)))
- {
- // Add the custom object
-
- AttachCxObj(Broker,ObjectList);
-
- // Any errors?
-
- if(!(Error = CxObjError(Broker)))
- {
- // Activate the broker
-
- ActivateCxObj(Broker,TRUE);
-
- return(0);
- }
- }
-
- if(Error & COERR_BADFILTER)
- Error = ERR_BadFilter;
- else
- {
- if(Error & COERR_BADTYPE)
- Error = ERR_BadType;
- else
- Error = ERROR_NO_FREE_STORE;
- }
- }
- else
- Error = Error - CBERR_SYSERR + ERR_SystemError;
- }
- else
- Error = ERR_NoMsgPort;
-
- ShutdownCx();
-
- return(Error);
- }
-
- /* SaverEntry():
- *
- * This background process handles the job of storing the
- * contents of the screen in the clipboard.
- */
-
- VOID __saveds
- SaverEntry()
- {
- struct BitMap *BitMap;
-
- // That's me
-
- Saver = (struct Process *)FindTask(NULL);
-
- ObtainSemaphoreShared(&BlankSemaphore);
-
- Forbid();
-
- // Create a bitmap to hold a copy of the screen
-
- if(BitMap = AllocBitMap(Width,Height,DisplayDepth,NULL,RPort -> BitMap))
- {
- STATIC ULONG Count = 1;
-
- UBYTE LocalBuffer[256];
- Object *Image;
-
- // Copy the contents
-
- BltBitMap(RPort -> BitMap,0,0,BitMap,0,0,Width,Height,0xC0,(1L << DisplayDepth) - 1,NULL);
-
- // Wait until they have arrived
-
- WaitBlit();
-
- Permit();
-
- ReleaseSemaphore(&BlankSemaphore);
-
- // Build a unique name, in case someone needs it
-
- SPrintf(LocalBuffer,"FracBlank_%ld×%ld×%ld_%ld",Width,Height,DisplayDepth,Count++);
-
- // Wrap the bitmap into an image object
-
- if(Image = NewDTObject(LocalBuffer,
- DTA_SourceType, DTST_RAM,
- DTA_GroupID, GID_PICTURE,
- PDTA_NumColors, 1L << DisplayDepth,
- PDTA_BitMap, BitMap,
- PDTA_ModeID, GetVPModeID(&BlankScreen -> ViewPort),
- TAG_DONE))
- {
- struct ColorRegister *ColourMap;
- struct BitMapHeader *BitMapHeader;
- ULONG *ColourTab;
-
- // Get the internal data storage pointers
-
- if(GetDTAttrs(Image,
- PDTA_BitMapHeader, &BitMapHeader,
- PDTA_ColorRegisters, &ColourMap,
- PDTA_CRegs, &ColourTab,
- TAG_DONE) == 3)
- {
- LONG i;
-
- // Fill in the header
-
- BitMapHeader -> bmh_Left = 0;
- BitMapHeader -> bmh_Top = 0;
- BitMapHeader -> bmh_Width = Width;
- BitMapHeader -> bmh_Height = Height;
- BitMapHeader -> bmh_Depth = DisplayDepth;
- BitMapHeader -> bmh_PageWidth = Width;
- BitMapHeader -> bmh_PageHeight = Height;
-
- // Fill in the colour tables
-
- for(i = 0 ; i < 1L << DisplayDepth ; i++)
- {
- ColourTab[i * 3 + 0] = Colours -> Entry[i] . Red;
- ColourTab[i * 3 + 1] = Colours -> Entry[i] . Green;
- ColourTab[i * 3 + 2] = Colours -> Entry[i] . Blue;
-
- ColourMap[i] . red = Colours -> Entry[i] . Red >> 24;
- ColourMap[i] . green = Colours -> Entry[i] . Green >> 24;
- ColourMap[i] . blue = Colours -> Entry[i] . Blue >> 24;
- }
-
- // Put the image into the clipboard
-
- DoMethod(Image,DTM_COPY,NULL);
- }
-
- DisposeDTObject(Image);
- }
- else
- FreeBitMap(BitMap);
- }
- else
- {
- Permit();
-
- ReleaseSemaphore(&BlankSemaphore);
- }
-
- Forbid();
-
- Saver = NULL;
- }
-
- /* HandleCxMsg(CxMsg *Message):
- *
- * Handle incoming Commodities messages.
- */
-
- VOID
- HandleCxMsg(CxMsg *Message)
- {
- ULONG MessageID = CxMsgID(Message),MessageType = CxMsgType(Message);
-
- ReplyMsg((struct Message *)Message);
-
- // Take a look at the message type
-
- switch(MessageType)
- {
- // It's a hotkey
-
- case CXM_IEVENT:
-
- switch(MessageID)
- {
- // Create the control panel
-
- case POP_WINDOW:
-
- // Make sure the blanker has terminated
-
- Signal(BlankerControlProcess,SIG_BREAK);
-
- SetupWindow();
-
- break;
-
- // Blank the screen
-
- case BLANK_SCREEN:
-
- if(!Window)
- {
- ObtainSemaphoreShared(&BlankSemaphore);
-
- if(!BlankTask)
- Signal(BlankerControlProcess,SIG_START);
- else
- {
- Signal(BlankerControlProcess,SIG_CHANGE);
-
- PatternCount = 0;
- }
-
- ReleaseSemaphore(&BlankSemaphore);
- }
-
- break;
-
- // Save the screen in the clipboard
-
- case SAVE_SCREEN:
-
- if(DataTypesBase)
- {
- ObtainSemaphoreShared(&BlankSemaphore);
-
- // Let the background process handle the job
-
- if(BlankScreen && !Saver)
- {
- CreateNewProcTags(
- NP_Name, "« FracBlank Screen Saver »",
- NP_Entry, SaverEntry,
- NP_StackSize, 4096,
- NP_WindowPtr, -1,
- TAG_DONE);
- }
-
- ReleaseSemaphore(&BlankSemaphore);
- }
-
- break;
- }
-
- break;
-
- // It's an internal Commodities command
-
- case CXM_COMMAND:
-
- switch(MessageID)
- {
- // Disable the Commodity
-
- case CXCMD_DISABLE:
-
- ActivateCxObj(Broker,FALSE);
- break;
-
- // Enable the Commodity
-
- case CXCMD_ENABLE:
-
- ActivateCxObj(Broker,TRUE);
- break;
-
- // Create the control panel
-
- case CXCMD_APPEAR:
- case CXCMD_UNIQUE:
-
- SetupWindow();
- break;
-
- // Close the control panel
-
- case CXCMD_DISAPPEAR:
-
- ShutdownWindow();
- break;
-
- // Remove this Commodity
-
- case CXCMD_KILL:
-
- CloseAll(RETURN_OK);
- break;
- }
-
- break;
- }
- }
-
- /* ShowTime(struct Gadget *SomeGadget,WORD Level):
- *
- * Gadtools support routine, displays the timeouts.
- */
-
- LONG __saveds __stdargs
- ShowTime(struct Gadget *SomeGadget,WORD Level)
- {
- STATIC UBYTE Buffer[30];
-
- if(Level)
- SPrintf(Buffer,"%2ld:%02ld min.",Level / 60,Level % 60);
- else
- SPrintf(Buffer,"«Off»");
-
- return((LONG)Buffer);
- }
-
- /* ShowDots(struct Gadget *SomeGadget,WORD Level):
- *
- * Cheap trick; multiply the number of dots by 100.
- */
-
- LONG __saveds __stdargs
- ShowDots(struct Gadget *SomeGadget,WORD Level)
- {
- return((LONG)Level * 100);
- }
-
- /* ShutdownWindow():
- *
- * Closes the control panel.
- */
-
- VOID
- ShutdownWindow()
- {
- if(Handle)
- {
- LT_DeleteHandle(Handle);
-
- Handle = NULL;
-
- Window = NULL;
-
- CloseLibrary(GTLayoutBase);
-
- GTLayoutBase = NULL;
- }
- }
-
- /* SetupWindow():
- *
- * Creates the control panel and disables the screen
- * blanker.
- */
-
- BOOL
- SetupWindow()
- {
- if(Handle)
- {
- LT_ShowWindow(Handle,TRUE);
-
- return(TRUE);
- }
- else
- {
- if(!(GTLayoutBase = SafeOpenLibrary("PROGDIR:gtlayout.library",9)))
- GTLayoutBase = SafeOpenLibrary("gtlayout.library",9);
-
- if(GTLayoutBase)
- {
- if(Handle = LT_CreateHandleTagList(NULL,NULL))
- {
- LT_New(Handle,
- LA_Type, VERTICAL_KIND,
- TAG_DONE);
- {
- LT_New(Handle,
- LA_LabelText, "Fractal screen blanker",
- LA_Type, VERTICAL_KIND,
- TAG_DONE);
- {
- STATIC STRPTR Copyright[] =
- {
- "Copyright © 1991-1995",
- "by Olaf `Olsen' Barthel",
- "All Rights Reserved",
- NULL
- };
-
- LT_New(Handle,
- LA_Type, BOX_KIND,
- LABX_Lines, Copyright,
- LABX_AlignText, ALIGNTEXT_CENTERED,
- LA_DrawBox, FALSE,
- TAG_DONE);
-
- LT_EndGroup(Handle);
- }
-
- LT_New(Handle,
- LA_LabelText, "Controls",
- LA_Type, VERTICAL_KIND,
- TAG_DONE);
- {
- STATIC STRPTR FractalTypes[] =
- {
- "Real plane",
- "Cosmic flames",
- "« Random »",
- NULL
- };
-
- STATIC STRPTR ColourModes[] =
- {
- "Cycling",
- "Static",
- NULL
- };
-
- LT_New(Handle,
- LA_Type, SLIDER_KIND,
- LA_LabelText, "Screen timeout",
- GTSL_Min, 0,
- GTSL_Max, 30 * 60,
- GTSL_LevelFormat, "%s",
- GTSL_DispFunc, ShowTime,
- LA_ULONG, &ScreenTimeout,
- LA_Chars, 20,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, SLIDER_KIND,
- LA_LabelText, "Pattern timeout",
- GTSL_Min, 0,
- GTSL_Max, 30 * 60,
- GTSL_LevelFormat, "%s",
- GTSL_DispFunc, ShowTime,
- LA_ULONG, &PatternTimeout,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, XBAR_KIND,
- TAG_DONE);
-
- EditHook . h_Entry = (HOOKFUNC)EditRoutine;
-
- LT_New(Handle,
- LA_Type, STRING_KIND,
- LA_LabelText, "Hot key",
- GTST_MaxChars, 255,
- GTST_String, HotkeyBuffer,
- GTST_EditHook, &EditHook,
- LA_ID, GAD_HOTKEY,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, STRING_KIND,
- LA_LabelText, "Blank screen",
- GTST_MaxChars, 255,
- GTST_String, BlankScreenBuffer,
- GTST_EditHook, &EditHook,
- LA_ID, GAD_BLANKSCREEN,
- TAG_DONE);
-
- if(DataTypesBase)
- {
- LT_New(Handle,
- LA_Type, STRING_KIND,
- LA_LabelText, "Save screen to clipboard",
- GTST_MaxChars, 255,
- GTST_String, SaveScreenBuffer,
- GTST_EditHook, &EditHook,
- LA_ID, GAD_SAVESCREEN,
- TAG_DONE);
- }
-
- LT_New(Handle,
- LA_Type, XBAR_KIND,
- TAG_DONE);
-
- UpdateModeString();
-
- LT_New(Handle,
- LA_Type, TEXT_KIND,
- LA_LabelText, "Display mode",
- LA_ID, GAD_MODE,
- GTTX_Text, DisplayModeBuffer,
- GTTX_Border, TRUE,
- LATX_Picker, TRUE,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, XBAR_KIND,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, CYCLE_KIND,
- LA_LabelText, "Colour mode",
- GTCY_Labels, ColourModes,
- LA_UBYTE, &ColourMode,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, CYCLE_KIND,
- LA_LabelText, "Fractal type",
- GTCY_Labels, FractalTypes,
- LA_UBYTE, &FractalType,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, SLIDER_KIND,
- LA_LabelText, "Maximum recursion level",
- GTSL_Min, 10,
- GTSL_Max, 100,
- GTSL_LevelFormat, "%ld",
- LA_ULONG, &MaxRecursionLevel,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, SLIDER_KIND,
- LA_LabelText, "Maximum dots",
- GTSL_Min, 10,
- GTSL_Max, 1000,
- GTSL_LevelFormat, "%lD",
- GTSL_DispFunc, ShowDots,
- LA_ULONG, &MaxFlamePoints,
- TAG_DONE);
-
- LT_EndGroup(Handle);
- }
-
- LT_New(Handle,
- LA_Type, VERTICAL_KIND,
- TAG_DONE);
- {
- LT_New(Handle,
- LA_Type, XBAR_KIND,
- LAXB_FullSize, TRUE,
- TAG_DONE);
-
- LT_EndGroup(Handle);
- }
-
- LT_New(Handle,
- LA_Type, HORIZONTAL_KIND,
- LAGR_Spread, TRUE,
- LAGR_SameSize, TRUE,
- TAG_DONE);
- {
- if(!MainProcess -> pr_CLI)
- {
- LT_New(Handle,
- LA_Type, BUTTON_KIND,
- LA_LabelText, "Save",
- LABT_ExtraFat, TRUE,
- LA_ID, GAD_SAVE,
- LA_Chars, 8,
- TAG_DONE);
- }
-
- LT_New(Handle,
- LA_Type, BUTTON_KIND,
- LA_LabelText, "Hide",
- LABT_ReturnKey, TRUE,
- LABT_ExtraFat, TRUE,
- LA_ID, GAD_HIDE,
- LA_Chars, 8,
- TAG_DONE);
-
- LT_New(Handle,
- LA_Type, BUTTON_KIND,
- LA_LabelText, "Quit",
- LA_ID, GAD_QUIT,
- TAG_DONE);
-
- LT_EndGroup(Handle);
- }
-
- LT_EndGroup(Handle);
- }
-
- if(Window = LT_Build(Handle,
- LAWN_IDCMP, IDCMP_CLOSEWINDOW,
- LAWN_BelowMouse, TRUE,
- LAWN_SmartZoom, TRUE,
- LAWN_TitleText, &VersTag[7],
- WA_DepthGadget, TRUE,
- WA_CloseGadget, TRUE,
- WA_DragBar, TRUE,
- WA_RMBTrap, TRUE,
- WA_Activate, TRUE,
- TAG_DONE))
- {
- ResetRequest = TRUE;
-
- return(TRUE);
- }
-
- LT_DeleteHandle(Handle);
-
- Handle = NULL;
- }
-
- ReportError(NULL,NULL,ERR_NoWindow);
-
- CloseLibrary(GTLayoutBase);
-
- GTLayoutBase = NULL;
- }
- else
- ReportError(NULL,NULL,ERR_NoGTLayout);
-
- return(FALSE);
- }
- }
-
- /* CloseAll(LONG ReturnCode):
- *
- * Free all resources and exit the program.
- */
-
- VOID
- CloseAll(LONG ReturnCode)
- {
- // Wait until the screen is saved
-
- while(Saver)
- Delay(TICKS_PER_SECOND);
-
- if(CxBase)
- ShutdownCx();
-
- if(BlankerControlProcess)
- {
- Forbid();
-
- SetSignal(0,SIG_HANDSHAKE);
-
- Signal(BlankerControlProcess,SIG_FINISH);
-
- Wait(SIG_HANDSHAKE);
-
- Permit();
- }
-
- if(Pointer)
- DisposeObject(Pointer);
-
- ShutdownWindow();
-
- if(Colours)
- FreeVec(Colours);
-
- if(ScreenModeRequest)
- FreeAslRequest(ScreenModeRequest);
-
- if(KeymapBase)
- CloseLibrary(KeymapBase);
-
- if(IconBase)
- CloseLibrary(IconBase);
-
- if(UtilityBase)
- CloseLibrary(UtilityBase);
-
- if(CxBase)
- CloseLibrary(CxBase);
-
- if(AslBase)
- CloseLibrary(AslBase);
-
- if(DataTypesBase)
- CloseLibrary(DataTypesBase);
-
- if(GfxBase)
- CloseLibrary(GfxBase);
-
- if(IntuitionBase)
- CloseLibrary(IntuitionBase);
-
- exit(ReturnCode);
- }
-
- /* OpenAll(int argc,char **argv):
- *
- * Open all resources, initialize the colour table and
- * create the Commodities interface.
- */
-
- VOID
- OpenAll(int argc,char **argv)
- {
- STRPTR *ToolTypes,
- String,
- Array[ARGCOUNT];
- struct RDArgs *Args;
- struct DiskObject *Icon;
- IX Expression;
- LONG Error;
-
- // Initialize this, the rotation code needs it
-
- deg45 = sin(-45.0);
-
- ScreenHook . h_Entry = (HOOKFUNC)BackfillDummy;
- WindowHook . h_Entry = (HOOKFUNC)BackfillDummy;
-
- InitSemaphore(&BlankSemaphore);
-
- MainProcess = (struct Process *)FindTask(NULL);
-
- // Open the libraries we need
-
- if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
- CloseAll(RETURN_FAIL);
-
- if(!(CxBase = OpenLibrary("commodities.library",37)))
- {
- ReportError(NULL,NULL,ERR_NoCommodities);
-
- CloseAll(RETURN_FAIL);
- }
-
- if(!(UtilityBase = OpenLibrary("utility.library",37)))
- {
- ReportError(NULL,NULL,ERR_NoUtility);
-
- CloseAll(RETURN_FAIL);
- }
-
- if(!(IconBase = OpenLibrary("icon.library",0)))
- {
- ReportError(NULL,NULL,ERR_NoIcon);
-
- CloseAll(RETURN_FAIL);
- }
-
- if(!(AslBase = OpenLibrary("asl.library",38)))
- {
- ReportError(NULL,NULL,ERR_NoAsl);
-
- CloseAll(RETURN_FAIL);
- }
-
- if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39)))
- {
- ReportError(NULL,NULL,ERR_NoGfx);
-
- CloseAll(RETURN_FAIL);
- }
-
- if(!(KeymapBase = OpenLibrary("keymap.library",37)))
- {
- ReportError(NULL,NULL,ERR_NoKeymap);
-
- CloseAll(RETURN_FAIL);
- }
-
- DataTypesBase = OpenLibrary("datatypes.library",39);
-
- if(!(ScreenModeRequest = AllocAslRequestTags(ASL_ScreenModeRequest,
- ASLSM_DoDepth, TRUE,
- ASLSM_PropertyFlags, NULL,
- ASLSM_PropertyMask, DIPF_IS_DUALPF | DIPF_IS_PF2PRI | DIPF_IS_HAM | DIPF_IS_EXTRAHALFBRITE,
- ASLSM_MinDepth, 1,
- ASLSM_MaxDepth, 8,
- ASLSM_UserData, FALSE,
- TAG_DONE)))
- {
- ReportError(NULL,NULL,ERR_ScreenModeRequest);
-
- CloseAll(RETURN_FAIL);
- }
-
- // Set up a transparent window pointer
-
- InitBitMap(&PointerBitMap,2,16,1);
-
- PointerBitMap . Planes[0] = PointerBitMap . Planes[1] = (PLANEPTR)&Nothing;
-
- if(!(Pointer = NewObject(NULL,POINTERCLASS,
- POINTERA_BitMap, &PointerBitMap,
- POINTERA_XOffset, 0,
- POINTERA_YOffset, 0,
- POINTERA_WordWidth, 2,
- TAG_DONE)))
- {
- ReportError(NULL,NULL,ERR_NoPointer);
-
- CloseAll(RETURN_FAIL);
- }
-
- if(!(Colours = (ColourTable *)AllocVec(sizeof(ColourTable) + 255 * sizeof(ColourEntry),MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR)))
- {
- ReportError(NULL,NULL,ERR_NoColours);
-
- CloseAll(RETURN_FAIL);
- }
-
- Forbid();
-
- if(BlankerControlProcess = CreateNewProcTags(
- NP_Name, "« FracBlank Control Process »",
- NP_Priority, 100,
- NP_Entry, BlankerControlEntry,
- NP_StackSize, 4096,
- NP_WindowPtr, -1,
- TAG_DONE))
- {
- SetSignal(0,SIG_HANDSHAKE);
-
- // Wait for handshake signal
-
- Wait(SIG_HANDSHAKE);
- }
-
- Permit();
-
- if(!BlankerControlProcess)
- {
- ReportError(NULL,NULL,ERR_NoControlProcess);
-
- CloseAll(RETURN_FAIL);
- }
-
- memset(Array,0,sizeof(Array));
-
- if(argc)
- {
- if(!(Args = ReadArgs("CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/K,BLANKSCREEN/K,SAVESCREEN/K,FRACTAL/K,COLOUR/K,DISPLAYMODE/K,DEPTH/N/K,SCREENTIMEOUT/K,PATTERNTIMEOUT/K,MAXRECURSION/N/K,MAXDOTS/N/K",(LONG *)Array,NULL)))
- {
- PrintFault(IoErr(),"FracBlank");
-
- CloseAll(RETURN_FAIL);
- }
-
- ToolTypes = NULL;
- Icon = NULL;
- }
- else
- {
- struct WBStartup *Startup = (struct WBStartup *)argv;
- BPTR OldDir;
-
- Args = NULL;
-
- OldDir = CurrentDir(MainProcess -> pr_HomeDir);
-
- if(Icon = GetDiskObject(Startup -> sm_ArgList -> wa_Name))
- ToolTypes = (STRPTR *)Icon -> do_ToolTypes;
- else
- ToolTypes = NULL;
-
- CurrentDir(OldDir);
- }
-
- NewBroker . nb_Pri = ToolValue(ToolTypes,"CX_PRIORITY",Array[ARG_PRIORITY] ? *(LONG *)Array[ARG_PRIORITY] : 0);
-
- if(NewBroker . nb_Pri < -128)
- NewBroker . nb_Pri = -128;
- else
- {
- if(NewBroker . nb_Pri > 127)
- NewBroker . nb_Pri = 127;
- }
-
- // We'll put up a mask of qualifiers we don't want the blanker
- // to stop at
-
- SpecialQualifier = IEQUALIFIER_REPEAT;
-
- // Set the Commodity popup hotkey if possible
-
- strcpy(HotkeyBuffer,ToolString(ToolTypes,"CX_POPKEY",Array[ARG_POPKEY] ? Array[ARG_POPKEY] : (STRPTR)"shift f1"));
-
- SpecialQualifier = AddQualifier(HotkeyBuffer,SpecialQualifier);
-
- if(Error = ParseIX(HotkeyBuffer,&Expression))
- {
- ReportError(NULL,"Invalid CX_POPKEY specification\n%s",ERR_BadFilter);
-
- CloseAll(RETURN_FAIL);
- }
-
- /* Determine the screen blanker hotkey. */
-
- strcpy(BlankScreenBuffer,ToolString(ToolTypes,"BLANKSCREEN",Array[ARG_BLANKSCREEN] ? Array[ARG_BLANKSCREEN] : (STRPTR)"shift f2"));
-
- SpecialQualifier = AddQualifier(BlankScreenBuffer,SpecialQualifier);
-
- if(Error = ParseIX(BlankScreenBuffer,&Expression))
- {
- ReportError(NULL,"Invalid BLANKSCREEN specification\n%s",ERR_BadFilter);
-
- CloseAll(RETURN_FAIL);
- }
-
- // Set the screen save hotkey
-
- strcpy(SaveScreenBuffer,ToolString(ToolTypes,"SAVESCREEN",Array[ARG_SAVESCREEN] ? Array[ARG_SAVESCREEN] : (STRPTR)"shift f3"));
-
- SpecialQualifier = AddQualifier(SaveScreenBuffer,SpecialQualifier);
-
- if(Error = ParseIX(SaveScreenBuffer,&Expression))
- {
- ReportError(NULL,"Invalid SAVESCREEN specification\n%s",ERR_BadFilter);
-
- CloseAll(RETURN_FAIL);
- }
-
- // Which fractal type?
-
- String = ToolString(ToolTypes,"FRACTAL",Array[ARG_FRACTAL] ? Array[ARG_FRACTAL] : (STRPTR)"RANDOM");
-
- if(MatchToolValue(String,"REALPLANE") || MatchToolValue(String,"REAL"))
- FractalType = FRACTAL_REAL_PLANE;
- else
- {
- if(MatchToolValue(String,"COSMICFLAME") || MatchToolValue(String,"COSMIC") || MatchToolValue(String,"FLAME"))
- FractalType = FRACTAL_COSMIC_FLAME;
- else
- FractalType = FRACTAL_RANDOM;
- }
-
- // Which colour mode?
-
- String = ToolString(ToolTypes,"COLOUR",Array[ARG_COLOUR] ? Array[ARG_COLOUR] : (STRPTR)"CYCLE");
-
- if(MatchToolValue(String,"STATIC"))
- ColourMode = COLOUR_STATIC;
- else
- ColourMode = COLOUR_CYCLE;
-
- // Which display mode?
-
- DisplayID = INVALID_ID;
-
- if(String = ToolString(ToolTypes,"DISPLAYMODE",Array[ARG_DISPLAYMODE]))
- {
- UBYTE LocalBuffer[40];
- ULONG ID = INVALID_ID;
-
- while((ID = NextDisplayInfo(ID)) != INVALID_ID)
- {
- if(GetModeName(ID,LocalBuffer))
- {
- if(!Stricmp(LocalBuffer,String))
- {
- struct DisplayInfo DisplayInfo;
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,ID))
- {
- if(!(DisplayInfo . NotAvailable & ~DI_AVAIL_NOTWITHGENLOCK))
- {
- if(!(DisplayInfo . PropertyFlags & (DIPF_IS_DUALPF | DIPF_IS_PF2PRI | DIPF_IS_HAM | DIPF_IS_EXTRAHALFBRITE)))
- {
- DisplayID = ID;
-
- break;
- }
- }
- }
- }
- }
- }
- }
-
- // Which depth?
-
- Depth = ToolValue(ToolTypes,"DEPTH",Array[ARG_DEPTH] ? *(LONG *)Array[ARG_DEPTH] : 0);
-
- if(Depth > 8)
- Depth = 8;
- else
- {
- if(Depth < 0)
- Depth = 0;
- }
-
- // Adjust the screen timeout if possible
-
- ScreenTimeout = GetSeconds(ToolString(ToolTypes,"SCREENTIMEOUT",Array[ARG_SCREENTIMEOUT] ? Array[ARG_SCREENTIMEOUT] : (STRPTR)"1:00"));
-
- // Adjust the pattern change timeout
-
- PatternTimeout = GetSeconds(ToolString(ToolTypes,"PATTERNTIMEOUT",Array[ARG_PATTERNTIMEOUT] ? Array[ARG_PATTERNTIMEOUT] : (STRPTR)"1:00"));
-
- // Take care of the recursion level
-
- MaxRecursionLevel = ToolValue(ToolTypes,"MAXRECURSION",Array[ARG_MAXRECURSION] ? *(LONG *)Array[ARG_MAXRECURSION] : 40);
-
- if(MaxRecursionLevel < 10)
- MaxRecursionLevel = 10;
- else
- {
- if(MaxRecursionLevel > 100)
- MaxRecursionLevel = 100;
- }
-
- // Now for the cosmic flame dots
-
- MaxFlamePoints = ToolValue(ToolTypes,"MAXDOTS",Array[ARG_MAXDOTS] ? *(LONG *)Array[ARG_MAXDOTS] : 20000);
-
- MaxFlamePoints /= 100;
-
- if(MaxFlamePoints < 10)
- MaxFlamePoints = 10;
- else
- {
- if(MaxFlamePoints > 1000)
- MaxFlamePoints = 1000;
- }
-
- // Create the commodities interface
-
- if(Error = SetupCx())
- {
- if(Error != ERR_Duplicate)
- ReportError(NULL,NULL,Error);
-
- if(Args)
- FreeArgs(Args);
-
- if(Icon)
- FreeDiskObject(Icon);
-
- CloseAll(RETURN_FAIL);
- }
-
- // Pop up the control panel if necessary
-
- if(MatchToolValue(ToolString(ToolTypes,"CX_POPUP",Array[ARG_POPUP] ? Array[ARG_POPUP] : (STRPTR)"no"),"yes"))
- {
- PopUp = TRUE;
-
- SetupWindow();
- }
-
- // Clean up
-
- if(Args)
- FreeArgs(Args);
-
- if(Icon)
- FreeDiskObject(Icon);
- }
-
- /* UpdateModeString():
- *
- * This routine builds the screen mode and screen depth string
- * for the user interface.
- */
-
- VOID
- UpdateModeString()
- {
- WORD Len;
-
- if(!GetModeName(DisplayID,DisplayModeBuffer))
- strcpy(DisplayModeBuffer,"«Default screen mode»");
-
- Len = strlen(DisplayModeBuffer);
-
- if(Depth)
- SPrintf(&DisplayModeBuffer[Len],", %ld colours",1L << Depth);
- else
- strcpy(&DisplayModeBuffer[Len],", «Maximum depth»");
- }
-
- /* SaveOptions(char **argv):
- *
- * Here we store the current options within the program icon.
- */
-
- VOID
- SaveOptions(char **argv)
- {
- STATIC STRPTR KnownTypes[] =
- {
- "CX_PRIORITY",
- "CX_POPKEY",
- "CX_POPUP",
- "BLANKSCREEN",
- "SAVESCREEN",
- "FRACTAL",
- "COLOUR",
- "DISPLAYMODE",
- "DEPTH",
- "SCREENTIMEOUT",
- "PATTERNTIMEOUT",
- "MAXRECURSION",
- "MAXDOTS"
- };
-
- struct WBStartup *Startup = (struct WBStartup *)argv;
- BPTR OldDir;
- struct DiskObject *Icon;
-
- OldDir = CurrentDir(MainProcess -> pr_HomeDir);
-
- // Get the program icon
-
- if(Icon = GetDiskObject(Startup -> sm_ArgList -> wa_Name))
- {
- STRPTR *Types,
- *NewTypes,
- Data;
- LONG Count = 0,Known = sizeof(KnownTypes) / sizeof(STRPTR),Len = 0,i;
-
- // Count the number of tooltypes present
-
- if(Types = (STRPTR *)Icon -> do_ToolTypes)
- {
- while(Types[Count])
- Count++;
- }
-
- // Count the room required for the tooltypes to add
-
- for(i = 0 ; i < Known ; i++)
- Len += strlen(KnownTypes[i]) + 2;
-
- // Add room for the keys
-
- Len += (10) + (256) + (4) + (256) + (256) + (8) + (8) + (40) + (10) + (10) + (10) + (10) + (10);
-
- // All the data will go here
-
- if(NewTypes = (STRPTR *)AllocVec(Len + (Count + 1 + Known) * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR))
- {
- STRPTR *Tool = NewTypes,String;
- UBYTE LocalBuffer[DISPLAYNAMELEN];
-
- Data = (STRPTR)&NewTypes[Count + 1 + Known];
-
- // CX_PRIORITY=[..]
-
- SPrintf(Data,"CX_PRIORITY=%ld",NewBroker . nb_Pri);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // CX_POPKEY=[..]
-
- SPrintf(Data,"CX_POPKEY=%s",HotkeyBuffer);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // CX_POPUP=[..]
-
- SPrintf(Data,"CX_POPUP=%s",PopUp ? "yes" : "no");
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // BLANKSCREEN=[..]
-
- SPrintf(Data,"BLANKSCREEN=%s",BlankScreenBuffer);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // SAVESCREEN=[..]
-
- SPrintf(Data,"SAVESCREEN=%s",SaveScreenBuffer);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // FRACTAL=[..]
-
- switch(FractalType)
- {
- case FRACTAL_REAL_PLANE:
-
- String = "REALPLANE";
- break;
-
- case FRACTAL_COSMIC_FLAME:
-
- String = "COSMICFLAME";
- break;
-
- case FRACTAL_RANDOM:
-
- String = "RANDOM";
- break;
- }
-
- SPrintf(Data,"FRACTAL=%s",String);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // COLOUR=[..]
-
- switch(ColourMode)
- {
- case COLOUR_CYCLE:
-
- String = "CYCLE";
- break;
-
- case COLOUR_STATIC:
-
- String = "STATIC";
- break;
- }
-
- SPrintf(Data,"COLOUR=%s",String);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // DISPLAYMODE=[..]
-
- if(GetModeName(DisplayID,LocalBuffer))
- {
- SPrintf(Data,"DISPLAYMODE=%s",LocalBuffer);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
- }
-
- // DEPTH=[..]
-
- SPrintf(Data,"DEPTH=%ld",Depth);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // SCREENTIMEOUT=[..]
-
- SPrintf(Data,"SCREENTIMEOUT=%ld:%02ld",ScreenTimeout / 60,ScreenTimeout % 60);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // PATTERNTIMEOUT=[..]
-
- SPrintf(Data,"PATTERNTIMEOUT=%ld:%02ld",PatternTimeout / 60,PatternTimeout % 60);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // MAXRECURSION=[..]
-
- SPrintf(Data,"MAXRECURSION=%ld",MaxRecursionLevel);
-
- *Tool++ = Data;
- Data += strlen(Data) + 1;
-
- // MAXDOTS=[..]
-
- SPrintf(Data,"MAXDOTS=%ld",MaxFlamePoints * 100);
-
- *Tool++ = Data;
-
- // Now add the remaining old tooltypes,
- // unless we already took care of them
-
- if(Types = (STRPTR *)Icon -> do_ToolTypes)
- {
- BOOL GotIt;
-
- while(*Types)
- {
- GotIt = FALSE;
-
- for(i = 0 ; i < Known ; i++)
- {
- if(!Strnicmp(*Types,KnownTypes[i],strlen(KnownTypes[i])))
- {
- GotIt = TRUE;
-
- break;
- }
- }
-
- if(!GotIt)
- *Tool++ = *Types;
-
- Types++;
- }
- }
-
- // Install the new tooltypes
-
- Icon -> do_ToolTypes = (char **)NewTypes;
-
- // Write the icon
-
- if(!PutDiskObject(Startup -> sm_ArgList -> wa_Name,Icon))
- ReportError(Window,"Error writing icon\n%s",IoErr());
-
- // Clean up
-
- FreeVec(NewTypes);
- }
- else
- ReportError(Window,NULL,ERROR_NO_FREE_STORE);
-
- FreeDiskObject(Icon);
- }
- else
- ReportError(Window,"Error reading icon\n%s",IoErr());
-
- CurrentDir(OldDir);
- }
-
- /* main(int argc,char **argv):
- *
- * That's where all the trouble starts.
- */
-
- void __stdargs
- main(int argc,char **argv)
- {
- ULONG SignalSet;
- BOOL Done = FALSE;
-
- // Open everything we need
-
- OpenAll(argc,argv);
-
- // Go into loop waiting for messages
-
- do
- {
- // Wait for a signal...
-
- SignalSet = SIG_CX | SIG_BREAK | SIG_WAKEUP;
-
- if(Window)
- SignalSet |= SIG_WINDOW;
-
- SignalSet = Wait(SignalSet);
-
- // Check the commodities toolkit reply port
-
- if(SignalSet & SIG_CX)
- {
- CxMsg *Message;
-
- while(Message = (CxMsg *)GetMsg(CxPort))
- HandleCxMsg(Message);
- }
-
- // ^C tells the program to quit
-
- if(SignalSet & SIG_BREAK)
- Done = TRUE;
-
- // ^F tells the program to open its control panel
-
- if(SignalSet & SIG_WAKEUP)
- SetupWindow();
-
- // If the control panel is still open,
- // check for new messages.
-
- if(Window)
- {
- if(SignalSet & SIG_WINDOW)
- {
- struct IntuiMessage *IMsg;
- BOOL Hide = FALSE;
- ULONG MsgClass;
- struct Gadget *MsgGadget;
- ULONG LocalID,LocalDepth;
- IX Expression;
- BOOL NewKeys;
- STRPTR String;
- LONG Error;
- struct IBox Box;
-
- while(IMsg = LT_GetIMsg(Handle))
- {
- MsgClass = IMsg -> Class;
- MsgGadget = (struct Gadget *)IMsg -> IAddress;
-
- LT_ReplyIMsg(IMsg);
-
- switch(MsgClass)
- {
- case IDCMP_CLOSEWINDOW:
-
- Hide = TRUE;
- break;
-
- case IDCMP_GADGETUP:
-
- switch(MsgGadget -> GadgetID)
- {
- case GAD_QUIT:
-
- Done = TRUE;
- break;
-
- // Make sure that the key
- // codes are correct
-
- case GAD_BLANKSCREEN:
- case GAD_SAVESCREEN:
- case GAD_HOTKEY:
-
- if(ParseIX(LT_GetString(Handle,MsgGadget -> GadgetID),&Expression))
- {
- DisplayBeep(Window -> WScreen);
-
- LT_Activate(Handle,MsgGadget -> GadgetID);
- }
-
- break;
-
- case GAD_HIDE:
- case GAD_SAVE:
-
- LT_LockWindow(Window);
-
- // Update the Commodities
- // interface only if the
- // key assignments have
- // changed
-
- NewKeys = FALSE;
-
- String = LT_GetString(Handle,GAD_HOTKEY);
-
- if(!ParseIX(String,&Expression))
- {
- IX OldExpression;
-
- ParseIX(HotkeyBuffer,&OldExpression);
-
- if(memcmp(&Expression,&OldExpression,sizeof(IX)))
- {
- SpecialQualifier = SubQualifier(HotkeyBuffer,SpecialQualifier);
-
- strcpy(HotkeyBuffer,String);
-
- SpecialQualifier = AddQualifier(HotkeyBuffer,SpecialQualifier);
-
- NewKeys = TRUE;
- }
- }
-
- String = LT_GetString(Handle,GAD_BLANKSCREEN);
-
- if(!ParseIX(String,&Expression))
- {
- IX OldExpression;
-
- ParseIX(BlankScreenBuffer,&OldExpression);
-
- if(memcmp(&Expression,&OldExpression,sizeof(IX)))
- {
- SpecialQualifier = SubQualifier(BlankScreenBuffer,SpecialQualifier);
-
- strcpy(BlankScreenBuffer,String);
-
- SpecialQualifier = AddQualifier(BlankScreenBuffer,SpecialQualifier);
-
- NewKeys = TRUE;
- }
- }
-
- String = LT_GetString(Handle,GAD_SAVESCREEN);
-
- if(!ParseIX(String,&Expression))
- {
- IX OldExpression;
-
- ParseIX(SaveScreenBuffer,&OldExpression);
-
- if(memcmp(&Expression,&OldExpression,sizeof(IX)))
- {
- SpecialQualifier = SubQualifier(SaveScreenBuffer,SpecialQualifier);
-
- strcpy(SaveScreenBuffer,String);
-
- SpecialQualifier = AddQualifier(SaveScreenBuffer,SpecialQualifier);
-
- NewKeys = TRUE;
- }
- }
-
- LT_UnlockWindow(Window);
-
- if(NewKeys)
- {
- if(Error = SetupCx())
- {
- if(Error != ERR_Duplicate)
- ReportError(Window,NULL,Error);
-
- CloseAll(RETURN_FAIL);
- }
- }
-
- if(MsgGadget -> GadgetID == GAD_HIDE)
- Hide = TRUE;
- else
- SaveOptions(argv);
-
- break;
- }
-
- break;
-
- // Pick a new display mode
-
- case IDCMP_IDCMPUPDATE:
-
- if(DisplayID == INVALID_ID)
- LocalID = GetVPModeID(&Window -> WScreen -> ViewPort);
- else
- LocalID = DisplayID;
-
- if(Depth)
- LocalDepth = Depth;
- else
- {
- struct DimensionInfo DimensionInfo;
-
- if(GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(DimensionInfo),DTAG_DIMS,LocalID))
- LocalDepth = DimensionInfo . MaxDepth;
- else
- LocalDepth = 2;
- }
-
- if(ScreenModeRequest -> sm_UserData && !ResetRequest)
- CopyMem(&ScreenModeRequest -> sm_LeftEdge,&Box,sizeof(struct IBox));
- else
- {
- CopyMem(&Window -> LeftEdge,&Box,sizeof(struct IBox));
-
- Box . Top += Window -> BorderTop;
- Box . Height -= Window -> BorderTop;
- }
-
- if(AslRequestTags(ScreenModeRequest,
- ASLSM_Window, Window,
- ASLSM_SleepWindow, TRUE,
- ASLSM_InitialDisplayID, LocalID,
- ASLSM_InitialDisplayDepth, LocalDepth,
- ASLSM_UserData, TRUE,
- ASLSM_InitialLeftEdge, Box . Left,
- ASLSM_InitialTopEdge, Box . Top,
- ASLSM_InitialWidth, Box . Width,
- ASLSM_InitialHeight, Box . Height,
- TAG_DONE))
- {
- ResetRequest = FALSE;
-
- DisplayID = ScreenModeRequest -> sm_DisplayID;
- Depth = ScreenModeRequest -> sm_DisplayDepth;
-
- UpdateModeString();
-
- LT_SetAttributes(Handle,GAD_MODE,
- GTTX_Text, DisplayModeBuffer,
- TAG_DONE);
- }
- else
- ResetRequest = TRUE;
-
- break;
- }
- }
-
- if(Hide)
- ShutdownWindow();
- }
- }
- }
- while(!Done);
-
- CloseAll(RETURN_OK);
- }
-